﻿using DG.Tweening;
using System;
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;

public class PaintView : MonoBehaviour
{
    #region 属性

    //绘图shader&material
    [SerializeField] private Shader _paintBrushShader;

    private Material _paintBrushMat;

    //清理renderTexture的shader&material
    [SerializeField] private Shader _clearBrushShader;

    private Material _clearBrushMat;

    //默认笔刷RawImage
    [SerializeField] private RawImage _defaultBrushRawImage;

    //默认笔刷&笔刷合集
    [SerializeField] private Texture _defaultBrushTex;

    //renderTexture
    private RenderTexture _renderTex;

    //默认笔刷RawImage
    [SerializeField] private Image _defaultColorImage;

    //绘画的画布
    [SerializeField] public RawImage _paintCanvas;

    //笔刷的默认颜色&颜色合集
    [SerializeField] private Color _defaultColor;

    //笔刷大小的slider
    private Text _brushSizeText;

    //笔刷的大小
    private float _brushSize;

    //屏幕的宽高
    private int _screenWidth;

    private int _screenHeight;

    //笔刷的间隔大小
    private float _brushLerpSize;

    //默认上一次点的位置
    private Vector2 _lastPoint;

    #endregion

    public bool isSure;
    public RectTransform ImagePool;

    private void Start()
    {
        StartCoroutine(WaitForNewRenderTexture());
    }

    #region 外部接口

    public void SetBrushSize(float size)
    {
        _brushSize = size;
        _paintBrushMat.SetFloat("_Size", _brushSize);
    }

    public void SetBrushTexture(Texture texture)
    {
        _defaultBrushTex = texture;
        _paintBrushMat.SetTexture("_BrushTex", _defaultBrushTex);
        _defaultBrushRawImage.texture = _defaultBrushTex;
    }

    public void SetBrushColor(Color color)
    {
        _defaultColor = color;
        _paintBrushMat.SetColor("_Color", _defaultColor);
        _defaultColorImage.color = _defaultColor;
    }

    /// <summary>
    /// 选择颜色
    /// </summary>
    /// <param name="image"></param>
    public void SelectColor(Image image)
    {
        SetBrushColor(image.color);
    }

    /// <summary>
    /// 选择笔刷
    /// </summary>
    /// <param name="rawImage"></param>
    public void SelectBrush(RawImage rawImage)
    {
        SetBrushTexture(rawImage.texture);
    }

    /// <summary>
    /// 设置笔刷大小
    /// </summary>
    /// <param name="value"></param>
    public void BrushSizeChanged(Slider slider)
    {
        //  float value = slider.maxValue + slider.minValue - slider.value;
        SetBrushSize(Remap(slider.value, 300.0f, 30.0f));
        if (_brushSizeText == null)
        {
            _brushSizeText = slider.transform.Find("Background/Text").GetComponent<Text>();
        }

        _brushSizeText.text = slider.value.ToString("f2");
    }

    /// <summary>
    /// 拖拽
    /// </summary>
    public void DragUpdate()
    {
        if (_renderTex && _paintBrushMat)
        {
            if (Input.GetMouseButton(0)) LerpPaint(Input.mousePosition);
        }
    }

    /// <summary>
    /// 拖拽结束
    /// </summary>
    public void DragEnd()
    {
        if (Input.GetMouseButtonUp(0))
        {
            _lastPoint = Vector2.zero;
            isSure = true;
        }
    }

    #endregion

    #region 内部函数

    //初始化数据
    public void InitData(float brushSize, Color color)
    {
        _defaultColor = color;
        _brushSize = brushSize;
        _brushLerpSize = (_defaultBrushTex.width + _defaultBrushTex.height) / 2.0f / _brushSize;
        _lastPoint = Vector2.zero;

        if (_paintBrushMat == null) UpdateBrushMaterial();

        if (_clearBrushMat == null) _clearBrushMat = new Material(_clearBrushShader);
        if (_renderTex == null)
        {
            _screenWidth = Screen.width;
            _screenHeight = Screen.height;

            //_renderTex = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24);
            _renderTex = RenderTexture.GetTemporary((int)_paintCanvas.GetComponent<RectTransform>().sizeDelta.x,
                (int)_paintCanvas.GetComponent<RectTransform>().sizeDelta.y, 24);
            _paintCanvas.texture = _renderTex;
        }

        Graphics.Blit(null, _renderTex, _clearBrushMat);
    }

    //更新笔刷材质
    private void UpdateBrushMaterial()
    {
        _paintBrushMat = new Material(_paintBrushShader);
        _paintBrushMat.SetTexture("_BrushTex", _defaultBrushTex);
        _paintBrushMat.SetColor("_Color", _defaultColor);
        _paintBrushMat.SetFloat("_Size", _brushSize);
    }

    //插点
    private void LerpPaint(Vector2 point)
    {
        Paint(point);

        if (_lastPoint == Vector2.zero)
        {
            _lastPoint = point;
            return;
        }

        float dis = Vector2.Distance(point, _lastPoint);
        if (dis > _brushLerpSize)
        {
            Vector2 dir = (point - _lastPoint).normalized;
            int num = (int)(dis / _brushLerpSize);
            for (int i = 0; i < num; i++)
            {
                Vector2 newPoint = _lastPoint + dir * (i + 1) * _brushLerpSize;
                Paint(newPoint);
            }
        }

        _lastPoint = point;
    }

    //画点
    private void Paint(Vector2 point)
    {
        if (point.x < 0 || point.x > _screenWidth || point.y < 0 || point.y > _screenHeight) return;

        Vector2 uv = new Vector2(point.x / (float)_screenWidth, point.y / (float)_screenHeight);
        _paintBrushMat.SetVector("_UV", uv);
        Graphics.Blit(_renderTex, _renderTex, _paintBrushMat);
    }

    /// <summary>
    /// 重映射  默认  value 为1-100
    /// </summary>
    /// <param name="value"></param>
    /// <param name="maxValue"></param>
    /// <param name="minValue"></param>
    /// <returns></returns>
    private float Remap(float value, float startValue, float enValue)
    {
        float returnValue = (value - 1.0f) / (100.0f - 1.0f);
        returnValue = (enValue - startValue) * returnValue + startValue;
        return returnValue;
    }

    #endregion

    private void OnDestroy()
    {
        _renderTex = null;
        GC.Collect();
        Resources.UnloadUnusedAssets();
    }

    #region 新增功能

    /// <summary>
    /// 确定
    /// </summary>
    public virtual void Sure()
    {
        if (!isSure) return;
        GameObject obj = Instantiate(_paintCanvas.gameObject,
            _paintCanvas.transform.position, Quaternion.identity, transform);
        obj.transform.localScale = _paintCanvas.transform.parent.localScale;
        obj.GetComponent<RectTransform>().DOLocalMove(Vector3.zero, 1).OnComplete(() =>
        {
            RectTransform rect = Instantiate(Resources.Load<RectTransform>("Image"),
                obj.transform.position, Quaternion.identity, ImagePool);
            obj.transform.SetParent(rect);
            obj.transform.localScale = new Vector3(0.8f, 0.8f, 1);
            rect.DOScale(Config.Instance.circleScale, 1);
            rect.GetComponent<RawImage>().texture =
                Config.Instance.circles[Random.Range(0, Config.Instance.circles.Count)];
            rect.GetComponent<Rigidbody2D>().AddForce(new Vector2(
                Random.Range(-1f, 1f), Random.Range(-1f, 1f)) * Random.Range(100, 150), ForceMode2D.Impulse);
            Config.Instance.childs.Add(rect);
            Config.Instance.CheckNum();
        });
        //StartCoroutine(SignatureSave());
        StartCoroutine(SignatureSave());
    }

    /// <summary>
    /// 清空_paintCanvas
    /// </summary>
    /// <returns></returns>
    IEnumerator WaitForNewRenderTexture()
    {
        isSure = false;
        yield return new WaitForSeconds(0.5f);
        _renderTex = new RenderTexture((int)_paintCanvas.GetComponent<RectTransform>().sizeDelta.x,
            (int)_paintCanvas.GetComponent<RectTransform>().sizeDelta.y, 24);
        _paintCanvas.texture = _renderTex;
        SetBrushColor(Config.Instance.brushColor);
    }

    /// <summary>
    /// 重写
    /// </summary>
    public void ReWrite()
    {
        StartCoroutine(WaitForNewRenderTexture());
    }

    #endregion

    //直接读取RenderTexture并保存
    public IEnumerator SignatureSave()
    {
        yield return new WaitForEndOfFrame();
        Texture texture = _paintCanvas.texture;
        File.WriteAllBytes(Application.streamingAssetsPath + "/Pics/" + DateTime.Now.Ticks + ".png",
            duplicateTexture(texture));
        StartCoroutine(WaitForNewRenderTexture());
    }

    //如果你想复制一张图片 就把注释打开 更改返回值就可以了
    private byte[] duplicateTexture(Texture source)
    {
        RenderTexture renderTex = RenderTexture.GetTemporary(
            source.width,
            source.height,
            0,
            RenderTextureFormat.Default,
            RenderTextureReadWrite.Linear);

        Graphics.Blit(source, renderTex);
        // RenderTexture previous = RenderTexture.active;
        RenderTexture.active = renderTex;
        Texture2D readableText = new Texture2D(source.width, source.height);
        readableText.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
        readableText.Apply();
        //这里可以转 JPG PNG EXR  Unity都封装了固定的Api
        byte[] bytes = readableText.EncodeToPNG();
        return bytes;
        //RenderTexture.active = previous;
        //RenderTexture.ReleaseTemporary(renderTex);
        //return readableText;
    }
}
